﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Framework
{
    public class ClickTrigger : MonoBehaviour, IPointerDownHandler, IPointerClickHandler, IPointerUpHandler
    {
        private List<UIClickListener> _listCsharpDownListener = new List<UIClickListener>();
        private List<UIClickListener> _listCsharpUpListener = new List<UIClickListener>();
        private List<UIClickListener> _listCsharpClickListener = new List<UIClickListener>();
        
        public static ClickTrigger Get(Transform transform)
        {
            ClickTrigger trigger = transform.GetComponent<ClickTrigger>();
            if (trigger == null)
            {
                trigger = transform.gameObject.AddComponent<ClickTrigger>();
            }
            return trigger;
        }
        
        void OnDestroy()
        {
            this._listCsharpDownListener = null;
            this._listCsharpUpListener = null;
            this._listCsharpClickListener = null;
        }

        public void AddClickListener(Action<object[]> callback, params object[] args)
        {
            int index = FindCSharpListener(_listCsharpClickListener, callback);
            if (index == -1)
            {
                UIClickListener clickListener = new UIClickListener(callback, args);
                _listCsharpClickListener.Add(clickListener);
            }
        }

        public void RemoveClickListener(Action<object[]> callback)
        {
            int index = FindCSharpListener(_listCsharpClickListener, callback);
            if (index != -1)
            {
                _listCsharpClickListener.RemoveAt(index);
            }
        }
        
        public void AddDownListener(Action<object[]> callback, params object[] args)
        {
            int index = FindCSharpListener(_listCsharpDownListener, callback);
            if (index == -1)
            {
                UIClickListener clickListener = new UIClickListener(callback, args);
                _listCsharpDownListener.Add(clickListener);
            }
        }

        public void RemoveDownListener(Action<object[]> callback)
        {
            int index = FindCSharpListener(_listCsharpDownListener, callback);
            if (index != -1)
            {
                _listCsharpDownListener.RemoveAt(index);
            }
        }
        
        public void AddUpListener(Action<object[]> callback, params object[] args)
        {
            int index = FindCSharpListener(_listCsharpUpListener, callback);
            if (index == -1)
            {
                UIClickListener clickListener = new UIClickListener(callback, args);
                _listCsharpUpListener.Add(clickListener);
            }
        }

        public void RemoveUpListener(Action<object[]> callback)
        {
            int index = FindCSharpListener(_listCsharpUpListener, callback);
            if (index != -1)
            {
                _listCsharpUpListener.RemoveAt(index);
            }
        }
        
        public void OnPointerDown(PointerEventData eventData)
        {
            int count = _listCsharpDownListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = _listCsharpDownListener[i];
                clickListener.Invoke(eventData);
            }
        }

        public void OnPointerClick(PointerEventData eventData)
        {
            int count = _listCsharpClickListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = _listCsharpClickListener[i];
                clickListener.Invoke(eventData);
            } 
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            int count = _listCsharpUpListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = _listCsharpUpListener[i];
                clickListener.Invoke(eventData);
            }
        }
        
        private int FindCSharpListener(List<UIClickListener> listListener, Action<object[]> callback)
        {
            int count = listListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = listListener[i];
                if (clickListener.Equals(callback))
                {
                    return i;
                }
            }
            return -1;
        }
    }
}